package com.hm.health.service;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;

import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.goodix.http.RawDataManager;
import com.goodix.http.jsonparams.response.BaseResponse;
import com.goodix.ini.HbdOptionIni;
import com.goodix.iot.libbase.logger.Glog;
import com.goodix.utils.ToastUtils;
import com.hm.health.MyApplication;

import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;

import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;


/**
 * Created by chenshi on 2020/6/16.
 */

public class RawdataUploadService extends Service {

    public static final String TAG = "RawdataUploadService";
    public static final String UPLOAD_ACTION = "com.goodix.ghbdtest.UPLOAD";
    public static final String UPLOAD_EXT_ACTION = "com.goodix.ghbdtest.UPLOAD_EXT";
    private static final String ROMA_TEST_DIR_NAME = "ROMA_TEST_DIR_NAME";

    private LinkedBlockingDeque<String> mFilePathList = new LinkedBlockingDeque<>();
    private Subscription mSubscription;
    private ExecutorService mExec;
    private boolean mIsUploadSuccess = false;
    private HbdOptionIni mHbdOptionIni;

    @Override
    public void onCreate() {
        super.onCreate();
        startWorkThread();
        registerBroadcast();
        mHbdOptionIni = MyApplication.getHbdOptionIni();
    }

    public static void uploadDirAndSubDir(Context context, String rootPath) {
        File dir = new File(rootPath);
        String[] dirs = dir.list();
        if (null == dirs) {
            return;
        }

        String[] dataDirs = new String[dirs.length + 1];
        for (int i = 0; i < dirs.length; ++i) {
            dataDirs[i] = rootPath + dirs[i] + "/";
        }

        dataDirs[dirs.length] = rootPath;

        RawdataUploadService.uploadDir(context, dataDirs);
    }

    public static void uploadDir(Context context, String[] dirs) {
        if (null == dirs || dirs.length == 0) {
            return;
        }

        for (String dir : dirs) {
            if(dir.contains("ecg_flash")) {
                uploadExtDir(context, dir);
            } else {
                uploadDir(context, dir);
            }
        }
    }

    public static void uploadExtDir(Context context, String dir) {

        if (!MyApplication.getHbdOptionIni().isUploadRawdata()) {
            Glog.d(TAG, "upload rawdata flag is false");
            return;
        }

        Intent intent =  new Intent();
        intent.setAction(UPLOAD_EXT_ACTION);
        intent.putExtra(ROMA_TEST_DIR_NAME, dir);
        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
        Glog.d(TAG, "send localBoradcast");
    }

    public static void uploadDir(Context context, String dir) {

        if (!MyApplication.getHbdOptionIni().isUploadRawdata()) {
            Glog.d(TAG, "upload rawdata flag is false");
            return;
        }

        Intent intent =  new Intent();
        intent.setAction(UPLOAD_ACTION);
        intent.putExtra(ROMA_TEST_DIR_NAME, dir);
        LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
        Glog.d(TAG, "send localBoradcast");
    }

    private void startWorkThread() {
        mExec = Executors.newSingleThreadExecutor();
        mExec.execute(() -> {
            while (true) {
                if (mFilePathList.isEmpty()) {
                    try {
                        Glog.d(TAG, "idle...");
                        Thread.sleep(1000 * 2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    try {
                        String filePath = mFilePathList.take();
                        uploadFile(filePath);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (null != mSubscription && !mSubscription.isUnsubscribed()) {
            mSubscription.unsubscribe();
            mSubscription = null;
        }

        if (null != mExec) {
            mExec.shutdownNow();
            mExec = null;
        }
    }

    private void registerBroadcast() {
        IntentFilter intentFilter = new IntentFilter(UPLOAD_ACTION);
        intentFilter.addAction(UPLOAD_EXT_ACTION);
        LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Glog.d(TAG, "onReceive yy");
                if (intent.getAction().equals(UPLOAD_ACTION)) {
                    Glog.d(TAG, "onReceive yy1");
                    String dir = intent.getStringExtra(ROMA_TEST_DIR_NAME);
                   File file = new File(dir);
                   File[] files = file.listFiles();
                   if (null != files && files.length > 0) {
                       for (File f : files) {
                           //for (String prefix : RawDataManager.PERFIXS) {
                               //if (f.getName().startsWith(prefix)) {
                           if (f.isDirectory()) {
                               continue;
                           }
                           if (f.getName().startsWith("uploaded-") || f.getName().startsWith("discard-")) {
                               continue;
                           }
                           mFilePathList.add(f.getAbsolutePath());
                           Glog.d(TAG, "upload file=" + f.getAbsolutePath());
                                   //break;
                               //}
                           //}
                       }
                   }
                } else if (intent.getAction().equals(UPLOAD_EXT_ACTION)) {
                    String dir = intent.getStringExtra(ROMA_TEST_DIR_NAME);
                    File file = new File(dir);
                    addAllFileInDir(file);
                }
            }
        }, intentFilter);
    }

    private void addAllFileInDir(File dir) {
        File files[]=dir.listFiles();
        if (null == files)
            return;
        for(File f:files){
            if(f.isDirectory()) {
                addAllFileInDir(f);
            } else {
                if (f.getName().startsWith("upload") || f.getName().startsWith("discard")) {
                    continue;
                }
                mFilePathList.add(f.getAbsolutePath());
            }
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    protected void uploadFile(String filePath) {
        mIsUploadSuccess = true;
        Object mSyncObject = new Object();
        Glog.d(TAG, "uploadFile: start send dir: " + filePath);
        mSubscription = RawDataManager.uploadFile(new File(filePath)).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<BaseResponse<String>>() {
                    @Override
                    public void onCompleted() {
                        String msg = "File upload successful!";
                        Glog.d(TAG, msg);
                        synchronized (mSyncObject) {
                            mSyncObject.notifyAll();
                        }
                        if(mHbdOptionIni != null && mHbdOptionIni.isShowHeartRateWave() && mIsUploadSuccess) {
                            ToastUtils.showShortToastMessage(getBaseContext(), msg);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        Glog.e(TAG, e.getMessage());
                        synchronized (mSyncObject) {
                            mSyncObject.notifyAll();
                        }
                        if(mHbdOptionIni != null && mHbdOptionIni.isShowHeartRateWave()) {
                            ToastUtils.showShortToastMessage(getBaseContext(), e.getMessage());
                        }
                        mIsUploadSuccess = false;
                    }

                    @Override
                    public void onNext(BaseResponse<String> stringBaseResponse) {
                        Glog.d(TAG, stringBaseResponse.getMsg());
                    }
                });

        try {
            synchronized (mSyncObject) {
                mSyncObject.wait(60 * 1000 * 30);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
